package audit

import (
	"counter-help/admin/server/global"
	"counter-help/admin/server/model/audit"
	auditReq "counter-help/admin/server/model/audit/request"
	"counter-help/admin/server/model/common/response"
	"counter-help/admin/server/utils"
	"errors"
	"fmt"
	"github.com/gin-gonic/gin"
	"go.uber.org/zap"
	"gorm.io/gorm"
	"io"
	"net/http"
	"os"
	"path/filepath"
)

type UserIdentityApi struct{}

// CreateIdentity 创建身份认证
func (api *UserIdentityApi) CreateOrUpdateIdentity(c *gin.Context) {
	// 绑定普通表单数据到模型
	var identity auditReq.UserIdentity
	if err := c.ShouldBind(&identity); err != nil {
		fmt.Printf("数据绑定失败: %v\n", err)
		//response.FailWithMessage("数据绑定失败", c)
		//return
	}

	// 获取上传的身份证正面和背面图片（可能为空）
	var frontImagePath, backImagePath string

	// 获取用户 ID 并设置存储路径
	userID := utils.GetUserID(c)
	if userID == 0 {

		response.FailWithMessage("用户登录已失效，请重新登录!", c)
		return
	}

	// 处理身份证正面图片
	frontImageFile, frontImageHeader, err := c.Request.FormFile("frontImage")
	if err == nil {
		imageDir := fmt.Sprintf("uploads/user_identities/front/%d", userID)

		// 检查并创建目录
		if err := os.MkdirAll(imageDir, os.ModePerm); err != nil {
			global.GVA_LOG.Error("创建存储目录失败!", zap.Error(err))
			response.FailWithMessage("创建存储目录失败", c)
			return
		}
		defer frontImageFile.Close()
		frontImagePath = fmt.Sprintf("%s/front_%s", imageDir, filepath.Base(frontImageHeader.Filename))
		// 清空目录中的所有文件
		files, err := os.ReadDir(imageDir)
		if err != nil {
			global.GVA_LOG.Error("读取存储目录失败!", zap.Error(err))
			response.FailWithMessage("读取存储目录失败", c)
			return
		}
		for _, file := range files {
			if err := os.Remove(fmt.Sprintf("%s/%s", imageDir, file.Name())); err != nil {
				global.GVA_LOG.Error("删除旧文件失败", zap.Error(err))
				response.FailWithMessage("删除旧文件失败", c)
				return
			}
		}

		// 保存正面图片到服务器
		frontOut, err := os.Create(frontImagePath)
		if err != nil {
			global.GVA_LOG.Error("身份证正面图片保存失败", zap.Error(err))
			response.FailWithMessage("身份证正面图片保存失败", c)
			return
		}
		defer frontOut.Close()
		if _, err := io.Copy(frontOut, frontImageFile); err != nil {
			global.GVA_LOG.Error("身份证正面图片写入失败", zap.Error(err))
			response.FailWithMessage("身份证正面图片写入失败", c)
			return
		}
	} else if err != http.ErrMissingFile {
		response.FailWithMessage("处理身份证正面图片时发生错误", c)
		return
	}

	// 处理身份证背面图片
	backImageFile, backImageHeader, err := c.Request.FormFile("backImage")
	if err == nil {
		imageDir := fmt.Sprintf("uploads/user_identities/back/%d", userID)
		fmt.Println("图片上传目录里", imageDir)
		// 检查并创建目录
		if err := os.MkdirAll(imageDir, os.ModePerm); err != nil {
			global.GVA_LOG.Error("创建存储目录失败!", zap.Error(err))
			response.FailWithMessage("创建存储目录失败", c)
			return
		}
		defer backImageFile.Close()
		backImagePath = fmt.Sprintf("%s/back_%s", imageDir, filepath.Base(backImageHeader.Filename))

		// 清空目录中的所有文件
		files, err := os.ReadDir(imageDir)
		if err != nil {
			global.GVA_LOG.Error("读取存储目录失败!", zap.Error(err))
			response.FailWithMessage("读取存储目录失败", c)
			return
		}
		for _, file := range files {
			if err := os.Remove(fmt.Sprintf("%s/%s", imageDir, file.Name())); err != nil {
				global.GVA_LOG.Error("删除旧文件失败", zap.Error(err))
				response.FailWithMessage("删除旧文件失败", c)
				return
			}
		}

		// 保存背面图片到服务器
		backOut, err := os.Create(backImagePath)
		if err != nil {
			global.GVA_LOG.Error("身份证背面图片保存失败", zap.Error(err))
			response.FailWithMessage("身份证背面图片保存失败", c)
			return
		}
		defer backOut.Close()
		if _, err := io.Copy(backOut, backImageFile); err != nil {
			global.GVA_LOG.Error("身份证背面图片写入失败", zap.Error(err))
			response.FailWithMessage("身份证背面图片写入失败", c)
			return
		}
	} else if err != http.ErrMissingFile {
		response.FailWithMessage("处理身份证背面图片时发生错误", c)
		return
	}
	if identity.RealName == "" {
		global.GVA_LOG.Error("真实姓名不能为空", zap.Error(err))
		response.FailWithMessage("真实姓名不能为空", c)
		return
	}

	if identity.DocumentType == "" {
		global.GVA_LOG.Error("证件类型不能为空", zap.Error(err))
		response.FailWithMessage("证件类型不能为空", c)
		return
	}
	if identity.DocumentNumber == "" {
		global.GVA_LOG.Error("证件号码不能为空", zap.Error(err))
		response.FailWithMessage("证件号码不能为空", c)
		return
	}
	// 构建身份认证记录，仅包含非空字段
	userIdentity := audit.UserIdentity{
		UserID:         userID,
		RealName:       identity.RealName,
		DocumentType:   identity.DocumentType,
		DocumentNumber: identity.DocumentNumber,
	}

	if frontImagePath != "" {
		userIdentity.FrontImagePath = frontImagePath
	}
	if backImagePath != "" {
		userIdentity.BackImagePath = backImagePath
	}

	// 创建或更新身份认证记录
	if err := auditUserIdentityService.CreateOrUpdateIdentity(userIdentity); err != nil {
		global.GVA_LOG.Error("创建或更新身份认证失败!", zap.Error(err))
		response.FailWithMessage("创建或更新身份认证失败", c)
		return
	}

	response.OkWithMessage("创建或更新身份认证成功", c)
}

// UpdateIdentity 更新身份认证
func (api *UserIdentityApi) UpdateIdentity(c *gin.Context) {
	var identity audit.UserIdentity
	if err := c.ShouldBindJSON(&identity); err != nil {
		response.FailWithMessage("数据绑定失败", c)
		return
	}

	identity.UserID = utils.GetUserID(c)
	if identity.UserID == 0 {

		response.FailWithMessage("用户登录已失效，请重新登录!", c)
		return
	}
	if err := auditUserIdentityService.UpdateIdentity(identity); err != nil {
		global.GVA_LOG.Error("更新身份认证失败!", zap.Error(err))
		response.CommonFailWithMessage("更新身份认证失败", c)
		return
	}

	response.OkWithMessage("更新身份认证成功", c)
}

// GetIdentity 获取用户身份认证信息
func (api *UserIdentityApi) GetIdentity(c *gin.Context) {
	userID := utils.GetUserID(c)
	if userID == 0 {
		response.FailWithMessage("用户登录已失效，请重新登录!", c)
		return
	}
	identity, err := auditUserIdentityService.GetIdentityByUserID(userID)
	if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) {
		global.GVA_LOG.Error("获取身份认证失败!", zap.Error(err))
		response.CommonFailWithMessage("获取身份认证失败", c)
		return
	}

	response.OkWithDetailed(identity, "获取身份认证成功", c)
}

// DeleteIdentity 删除身份认证
func (api *UserIdentityApi) DeleteIdentity(c *gin.Context) {
	userID := utils.GetUserID(c)
	if err := auditUserIdentityService.DeleteIdentity(userID); err != nil {
		global.GVA_LOG.Error("删除身份认证失败!", zap.Error(err))
		response.FailWithMessage("删除身份认证失败", c)
		return
	}

	response.OkWithMessage("删除身份认证成功", c)
}

// ApproveIdentity 审核通过身份认证
func (api *UserIdentityApi) ApproveIdentity(c *gin.Context) {
	var request struct {
		UserID uint `json:"userId" form:"userId" binding:"required"`
	}
	if err := c.ShouldBindJSON(&request); err != nil {
		response.FailWithMessage("数据绑定失败", c)
		return
	}

	// 更新身份认证为审核通过
	if err := auditUserIdentityService.UpdateIdentityStatus(request.UserID, true, true, ""); err != nil {
		global.GVA_LOG.Error("审核通过失败!", zap.Error(err))
		response.FailWithMessage("审核通过失败", c)
		return
	}

	response.OkWithMessage("审核通过成功", c)
}

// RejectIdentity 审核不通过身份认证
func (api *UserIdentityApi) RejectIdentity(c *gin.Context) {
	var request struct {
		UserID          uint   `json:"userId" form:"userId" binding:"required"`
		RejectionReason string `json:"rejectionReason" form:"rejectionReason" binding:"required"`
	}
	if err := c.ShouldBindJSON(&request); err != nil {
		response.FailWithMessage("数据绑定失败", c)
		return
	}

	// 更新身份认证为审核不通过，并设置驳回理由
	if err := auditUserIdentityService.UpdateIdentityStatus(request.UserID, true, false, request.RejectionReason); err != nil {
		global.GVA_LOG.Error("审核不通过失败!", zap.Error(err))
		response.FailWithMessage("审核不通过失败", c)
		return
	}

	response.OkWithMessage("审核不通过成功", c)
}

// GetPendingIdentities 获取所有未审核的身份认证记录
func (api *UserIdentityApi) GetPendingIdentities(c *gin.Context) {
	pendingIdentities, err := auditUserIdentityService.GetPendingIdentities()
	if err != nil {
		global.GVA_LOG.Error("获取未审核身份认证记录失败!", zap.Error(err))
		response.FailWithMessage("获取未审核身份认证记录失败", c)
		return
	}
	response.OkWithDetailed(pendingIdentities, "获取未审核身份认证记录成功", c)
}

// GetApprovedIdentities 获取所有已审核的身份认证记录
func (api *UserIdentityApi) GetApprovedIdentities(c *gin.Context) {
	approvedIdentities, err := auditUserIdentityService.GetApprovedIdentities()
	if err != nil {
		global.GVA_LOG.Error("获取已审核身份认证记录失败!", zap.Error(err))
		response.FailWithMessage("获取已审核身份认证记录失败", c)
		return
	}
	response.OkWithDetailed(approvedIdentities, "获取已审核身份认证记录成功", c)
}
